package com.itaem.community.modules.infrastructure.user.controller;


import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.itaem.community.core.annotations.ResponseResult;
import com.itaem.community.core.entity.PageData;
import com.itaem.community.core.exception.common.IllegalParameterException;
import com.itaem.community.modules.infrastructure.user.dto.*;
import com.itaem.community.modules.infrastructure.user.entity.UserPhoneEntity;
import com.itaem.community.modules.infrastructure.user.service.UserPhoneService;
import com.itaem.community.modules.infrastructure.user.service.UserService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.authz.AuthorizationException;
import org.apache.shiro.crypto.hash.Sha256Hash;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;


/**
 * <p>
 * 用户信息 前端控制器
 * </p>
 *
 * @author tomato
 * @since 2020-10-28
 */
@Api(tags = "用户信息管理模块")
@ResponseResult
@RestController
@Slf4j
@RequestMapping("/user")
public class UserController {

    @Autowired
    private UserService userService;

    @Autowired
    private UserPhoneService userPhoneService;

//    @RequiresRoles(value = {"超级管理员","物业工作人员"}, logical = Logical.OR)
    @ApiOperation("分页查询用户信息")
    @GetMapping("/{page}/{size}")
    public PageData<UserDTO> list(
            @ApiParam(value = "页码", example = "1") @PathVariable Long page,
            @ApiParam(value = "大小", example = "15") @PathVariable Long size) {
        return userService.pageUsers(page, size);
    }


//    @RequiresRoles(value = {"超级管理员","物业工作人员"}, logical = Logical.OR)
    @ApiOperation("获取单个用户的信息")
    @GetMapping("/{id}")
    public UserDTO info(@ApiParam(value = "要查询的用户id", example = "1") @PathVariable Integer id)
            throws IllegalParameterException {
        if (id == null || id < 0) {
            throw new IllegalParameterException("请提交合法id");
        }
        log.info(userService.toString());
        return userService.getUserById(id);
    }

    @ApiOperation("使用手机号注册")
    @PostMapping("/phone")
    public Boolean saveWithPhoneNumber(@Valid @RequestBody UserPhoneCreateDTO phoneDto) {
        return userService.saveUserByPhoneNumber(phoneDto);
    }

    @ApiOperation("使用手机号登录")
    @PostMapping("/login")
    public UserDTO login(@Valid @RequestBody UserLoginDTO loginDto) {
        Subject subject = SecurityUtils.getSubject();
        UserPhoneEntity userPhoneEntity = userPhoneService.getOne(
                new QueryWrapper<UserPhoneEntity>().eq("phone_number",loginDto.getPhoneNumber()));
        if(userPhoneEntity == null){
            throw new IllegalParameterException("用户不存在");
        }
        log.info(new Sha256Hash(loginDto.getPassword(), userPhoneEntity.getSalt()).toHex());
        UsernamePasswordToken usernamePasswordToken = new UsernamePasswordToken(
                loginDto.getPhoneNumber(),
                new Sha256Hash(loginDto.getPassword(), userPhoneEntity.getSalt()).toHex()
        );
        try{
            subject.login(usernamePasswordToken);
        }catch(UnknownAccountException e){
            log.error("用户不存在", e);
            throw new IllegalParameterException("用户不存在");
        }catch(AuthenticationException e){
            log.error("手机号或密码错误", e);
            throw new IllegalParameterException("手机号或密码错误");
        }catch(AuthorizationException e){
            log.error("没有权限", e);
            throw new IllegalParameterException("没有权限");
        }
        return userService.getUserById(userPhoneEntity.getUserId());
    }


//    @RequiresRoles(value = {"超级管理员","物业工作人员","业主","维修工"}, logical = Logical.OR)
    @ApiOperation("更新手机号登录时使用的密码")
    @PutMapping("/phone")
    public Boolean updatePhoneLoginPassword(@Valid @RequestBody UserPhoneUpdateDTO phoneUpdateDto) {
        return userService.updatePhoneLoginPassword(phoneUpdateDto);
    }

    @ApiOperation("使用微信注册")
    @PostMapping("/wechat")
    public Boolean saveWithWechat(@Valid @RequestBody UserWechatCreateDTO wechatDto) {
        return userService.saveUserByWechatNumber(wechatDto);
    }


//    @RequiresRoles(value = {"超级管理员","物业工作人员","业主","维修工"}, logical = Logical.OR)
    @ApiOperation("更新用户信息")
    @PatchMapping
    public Boolean update(@Valid @RequestBody UserUpdateDTO dto) {
        return userService.updateUser(dto);
    }

//    @RequiresRoles(value = {"超级管理员","物业工作人员","业主","维修工"}, logical = Logical.OR)
    @ApiOperation("实名认证")
    @PutMapping("/authentication")
    public Boolean realNameAuthentication(@Valid @RequestBody UserIdCardAuthenticationDTO authenticationDto) {
        return userService.idCardAuthenticate(authenticationDto);
    }

//    @RequiresRoles(value = {"超级管理员","物业工作人员"}, logical = Logical.OR)
    @ApiOperation("删除用户")
    @DeleteMapping("/{id}")
    public Boolean remove(@ApiParam("要删除的用户id") @PathVariable Integer id) {
        return userService.removeUserById(id);
    }
}

